﻿#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

//main111&112&113&114&115：内存操作函数memset和memcpy和memmove和memcmp和二级指针实现堆内存冒泡排序
int main111()
{
	int* p = (int*)malloc(sizeof(int) * 10);

	//2.memset的参数：目标，值，字节大小；当值为1时，p[i]为01010101，16进制存储，即p[i]=16843009；故0是有效值；
		//主要用来初始化堆内存；
	memset(p, 0, 40);
	for (int i = 0; i < 10; i++)
	{
		printf("1.使用memset函数将指针p指向的堆空间内存重置为0，即p[i]：%d\n", p[i]);//0,0,0...
	}
	free(p);

	char* pCh = (char*)malloc(sizeof(char) * 10);
	memset(pCh, 65, 10);
	printf("3.使用memset函数将指针pCh指向的堆空间内存重置为A，即p指向的堆内存空间值：%s\n", pCh);//AAAAAAAAAA
	free(pCh);

	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	memset(arr, 0, 40);
	for (int i = 0; i < 10; i++)
	{
		printf("4.使用memset函数初始化栈内存数组的数据，即arr[i]：%d\n", arr[i]);//0,0,0...
	}

	system("pause");
	return EXIT_SUCCESS;
}
int main112(void)
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int* p = (int*)malloc(sizeof(int) * 10);
	memcpy(p, arr, 40);
	for (int i = 0; i < 10; i++)
	{
		printf("5.使用memcpy函数将栈区数组arr拷贝到堆区指针p指向的内存空间，即p[i]：%d\n", p[i]);//1,2,3...10
	}

	free(p);

	memcpy(&arr[2], arr, 20);
	for (int i = 0; i < 10; i++)
	{
		printf("6.将数组arr从首地址起，拷贝到arr[2]处，拷贝5个元素，则arr[i]：%d\n", arr[i]);//1,2,1,2,3,4,5,8,9,10
	}

	//8.strcpy拷贝的时候，是以src字符串\0结尾拷贝的。要是像arrCh这样，会拷贝到乱码；
	char arrCh[] = { 'h','e','l','l','o' };
	char* pCh = (char*)malloc(100);
	//strcpy(pCh, arrCh);
	//printf("7.使用strcpy函数，将字符数组arrch拷贝到指针pCh指向的堆内存空间，即pCh指向的内存值为：%s\n", pCh);//hello烫烫烫烫烫?

	//10.在拷贝之前，先将指针pCh指向的内存空间，初始化为0，否则会出现pCh指向的内存空间为：hello屯屯屯屯屯
	memset(pCh, 0, 100);
	memcpy(pCh, arrCh, 5);
	printf("9.使用memcpy函数，将字符数组arrch拷贝到指针pCh指向的堆内存空间，即pCh指向的内存值为：%s\n", pCh);//hello屯屯屯屯屯-->hello

	//11.strcpy和memcpy的不同：
		//1.函数参数不同；2.strcpy拷贝字符串，memcpy拷贝一块内存；
		//3.拷贝结束标志不同，strcpy以\0结尾，memcpy以拷贝个数为结尾；
	free(pCh);

	return 0;
}
int main113(void)
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	//13.memmove拷贝重叠内存地址不会出现问题，但是效率比较低。如果拷贝的源和目标，没有重叠，则和memcpy函数效率一样。
	memmove(&arr[2], arr, 20);
	for (int i = 0; i < 10; i++)
	{
		printf("12.将数组arr从首地址起，拷贝到arr[2]处，拷贝5个元素，则arr[i]：%d\n", arr[i]);//1,2,1,2,3,4,5,8,9,10
	}

	return 0;
}
int main114(void)
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[10] = { 1,2,3,4 };

	//15.相等为0，大于为1，小于为-1；
	int val = memcmp(arr1, arr2, 20);//4-->20
	printf("14.使用memcmp函数，比较arr1和arr2的4个字节的内存的值，输出比较结果val：%d\n", val);//0-->1

	if (!memcmp(arr1, arr2, 8))
	{
		printf("16.数组arr1和arr2的前两个元素内容相等！\n");//16.数组arr1和arr2的前两个元素内容相等！
	}

	int* p1 = (int*)malloc(sizeof(int) * 10);
	char* p2 = (char*)malloc(sizeof(char) * 40);

	memcpy(p1, "hello", 6);
	memcpy(p2, "hello", 6);
	if (!memcmp(p1, p2, 6))
	{
		printf("17.指针p1和p2分别指向的堆内存空间值相等！\n");//17.指针p1和p2分别指向的堆内存空间值相等！
	}
	else
	{
		printf("18.指针p1和p2分别指向的堆内存空间值不相等！\n");
	}
	printf("19.输出指针p1和p2分别指向的堆内存空间值：%s---%s\n", p1, p2);//hello-hello

	free(p1);
	free(p2);

	int a = 0xffff;//10-->65535
	//24.char存的值超范围，故值为-1；int类型a的内存第一个字节，也存的是-1；
	char b = 0xffff;//10--->65535
	//22.int类型占4个字节，10存在取的第一个字节中；
	if (!memcmp(&a, &b, 1))
	{
		printf("20.int类型变量a和char类型变量b，比较两者1个字节的栈内存值，结果相等！\n");//20.int类型变量a和char类型变量b，比较两者1个字节的栈内存值，结果相等！
	}
	else
	{
		printf("21.int类型变量a和char类型变量b，比较两者1个字节的栈内存值，结果不相等！\n");
	}
	printf("23.输出a和b的值：%d---%d\n", a, b);//10---10 --->65535--- -1
	return 0;
}
int main115(void)
{
	//25.练习：求出三名学生，三门功课成绩，并排序，通过堆空间来实现。
	int** p = (int**)malloc(sizeof(int*) * 3);
	p[0] = (int*)malloc(sizeof(int) * 3);
	p[1] = (int*)malloc(sizeof(int) * 3);
	p[2] = (int*)malloc(sizeof(int) * 3);

	p[0][0] = 90;
	p[0][1] = 80;
	p[0][2] = 70;

	p[1][0] = 94;
	p[1][1] = 91;
	p[1][2] = 89;

	p[2][0] = 92;
	p[2][1] = 86;
	p[2][2] = 82;

	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			for (int k = 0; k < 2 - j; k++)
			{
				if (p[i][k] > p[i][k + 1])
				{
					int temp = p[i][k];
					p[i][k] = p[i][k + 1];
					p[i][k + 1] = temp;
				}
			}
		}
	}

	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			printf("26.输出学生的成绩排名，p[%d][%d]=%d\n", i, j, p[i][j]);//p[0][0]=70 p[0][1]=80 p[0][2]=90 p[1][0]=89 p[1][1]=91 p[1][2]=94 p[2][0]=82 p[2][1]=86 p[2][2]=92
		}
	}

	free(p[0]);
	free(p[1]);
	free(p[2]);
	free(p);

	return 0;
}